#include "rk_defines.h"
#include "rk_debug.h"
#include "rknn_api.h"

#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <string>
#include <vector>
#include <cmath>

#include "taiic_avsr.h"
#include "taiic_rknn.h"

/*
rknntoolkit_1.5.0  output_type is int8, need use zp and  scale to trans float
*/

static inline int64_t getCurrentTimeUs()
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return tv.tv_sec * 1000000 + tv.tv_usec;
}

int main(int argc, char *argv[])
{
  AVSR_TOOLKIT_MODEL_CTX_S *avsr_ctx; // 模型推理相关

  char *input_path = argv[2]; // audio

  // 模型推理相关
  avsr_ctx = reinterpret_cast<AVSR_TOOLKIT_MODEL_CTX_S *>(malloc(sizeof(AVSR_TOOLKIT_MODEL_CTX_S))); // 分配内存空间
  memset(avsr_ctx, 0, sizeof(AVSR_TOOLKIT_MODEL_CTX_S));

  avsr_ctx->modelPath = argv[1]; // 模型存放路径

  avsr_rknn_toolkit_config_init(avsr_ctx);
  avsr_rknn_toolkit_io_init(avsr_ctx);

  // Get Input Data(Audio) From CPU
  int i = 0;
  unsigned char *input_data[avsr_ctx->io_num.n_input];

  input_data[i] = new unsigned char[avsr_ctx->input_attrs[i].size]; // 设置输入大小
  FILE *fp = fopen(input_path, "rb");
  printf("==load input file data is %s==\n", input_path);
  if (fp == NULL)
  {
    perror("open failed!");
    return -1;
  }
  fread(input_data[i], avsr_ctx->input_attrs[i].size, 1, fp);
  fclose(fp);
  if (!input_data[i])
  {
    return -1;
  }

  avsr_rknn_toolkit_data_refresh(avsr_ctx, input_data);

  int64_t start_us = getCurrentTimeUs();
  // Set input
  int ret = rknn_run(avsr_ctx->context, NULL);
  if (ret < 0)
  {
    RK_LOGE("===rknn_run_fail! ret = %d\n", ret);
    return -1;
  }
  int64_t elapse_us = getCurrentTimeUs() - start_us;
  printf(" Elapse Time = %.2fms, FPS = %.2f\n", elapse_us / 1000.f, 1000.f * 1000.f / elapse_us);

  MODEL_RESULT_S rknn_result = avsr_rknn_toolkit_result_int8(avsr_ctx);

  printf("===result label is %d, prob is %f====\n", rknn_result.label, rknn_result.prob);

  // destroy
  rknn_destroy(avsr_ctx->context);

  for (int i = 0; i < avsr_ctx->io_num.n_input; i++)
  {
    free(input_data[i]);
  }

  return 0;
}